package com.yanqu.road.logic.activity.evefeast;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.evefeast.EveFeastBlock;
import com.yanqu.road.entity.activity.evefeast.EveFeastGameData;
import com.yanqu.road.entity.activity.evefeast.EveFeastItem;
import com.yanqu.road.entity.activity.evefeast.EveFeastLogItem;
import com.yanqu.road.entity.activity.evefeast.config.*;
import com.yanqu.road.entity.config.system.PropertyWeightItem;
import com.yanqu.road.logic.activity.evefeast.enums.eEveFeastBuffType;
import com.yanqu.road.logic.activity.evefeast.enums.eEveFeastEffectType;
import com.yanqu.road.logic.activity.evefeast.enums.eEveFeastShowType;
import com.yanqu.road.logic.activity.evefeast.enums.eEveFeastTriggerType;
import com.yanqu.road.logic.helper.RandomWeightConfigHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class EveFeastGameLogic {
    private static Logger logger = LogManager.getLogger(EveFeastGameLogic.class.getName());
    public final static int HIGH = 5; //高
    public final static int WIDTH = 4; //宽

    private EveFeastConfig config;
    private List<List<EveFeastShowInfo>> showInfoListList = new ArrayList<>();
    private int showGroupId = 1;
    private RandomHelper randomHelper;
    /**
     * 被消除的物品
     */
    private List<EveFeastLogItem> eliminateItemList = new ArrayList<>();
    /**
     * 新增的物品
     */
    private List<Integer> addItemIds = new ArrayList<>();
    private boolean isNextRound = false;
    private boolean isNextTurn = false;
    private boolean isEnd = false;
    private boolean isPass = false;
    private int refreshAdd = 0;
    private int removeAdd = 0;
    private EveFeastBlock lastShowBlock = null;

    private EveFeastBlock loopBlock;

    /**
     * 本局产生的总雅趣值
     */
    private int scoreAmount = 0;

    /**
     * 添加物品后要触发效果的格子
     */
    private LinkedList<EveFeastBlock> waitTriggerBlockList = new LinkedList<>();
    /**
     * 初始放置时的物品记录
     */
    private List<EveFeastLogItem> initOnItemList = new ArrayList<>();
    /**
     * 添加物品时的放置记录
     */
    private List<EveFeastLogItem> addPlaceOnItemList = new ArrayList<>();

    public EveFeastGameLogic(EveFeastConfig config, RandomHelper randomHelper) {
        this.config = config;
        this.randomHelper = randomHelper;
    }

    public EveFeastGameData createNewGameData(EveFeastMissionConfig missionConfig, boolean isBuyToken1, boolean isBuyToken2) {
        EveFeastGameData gameData = new EveFeastGameData();
        gameData.setTurnId(missionConfig.getTurnId());
        gameData.setRound(1);

        List<List<EveFeastBlock>> listList = new ArrayList<>();
        //初始化格子
        for (int y = 0; y < HIGH; y++) {
            List<EveFeastBlock> yList = new ArrayList<>(WIDTH);
            listList.add(yList);
            for (int x = 0; x < WIDTH; x++) {
                EveFeastBlock block = new EveFeastBlock();
                block.setX(x);
                block.setY(y);
                block.setObjectId(0);
                yList.add(block);
            }
        }
        gameData.setBlocks(listList);

        //初始物品
        List<Integer> initItemIds = new ArrayList<>();
        if (missionConfig.getMission() == 0) {
            initItemIds = config.getTryInitItemIdList();
        } else {
            initItemIds = config.getInitItemIdList();
        }
        for (Integer itemId : initItemIds) {
            addNewGameItem(gameData, itemId);
        }

        if (isBuyToken2) {//高级战令效果,有专门的随机池
            Map<Integer, Integer> token2RandomPool = config.getToken2RandomPool();
            for (int i = 0; i < 3; i++) {
                Integer itemId = RandomHelper.getRandomKeyByWeight(token2RandomPool);
                addChoseItem(gameData, itemId);
                token2RandomPool.remove(itemId);
            }
        } else {
            List<Integer> itemIds = config.randomItemList(gameData, missionConfig, 3);
            for (Integer itemId : itemIds) {
                addChoseItem(gameData, itemId);
            }
        }

        //初始免费次数
        gameData.setRefreshTimes(missionConfig.getRefreshTimes());
        gameData.setRemoveTimes(missionConfig.getRemoveTimes());
        //战令加次数
        if (isBuyToken1) {
            List<Integer> token1Params = config.getToken1Params();
            if (token1Params.size() > 0) {
                gameData.setRefreshTimes(gameData.getRefreshTimes() + token1Params.get(0));
            }
            if (token1Params.size() > 1) {
                gameData.setRemoveTimes(gameData.getRemoveTimes() + token1Params.get(1));
            }
        }

        if (isBuyToken2) {
            List<Integer> token2Params = config.getToken2Params();
            if (token2Params.size() > 0) {
                gameData.setRefreshTimes(gameData.getRefreshTimes() + token2Params.get(0));
            }
            if (token2Params.size() > 1) {
                gameData.setRemoveTimes(gameData.getRemoveTimes() + token2Params.get(1));
            }
        }
        return gameData;
    }

    public EveFeastItem createNewGameItem(EveFeastGameData gameData, int itemId) {
        EveFeastObjectConfig itemConfig = config.getItemConfig(itemId);
        if (itemConfig == null) {
            return null;
        }

        int maxId = 0;
        for (EveFeastItem haveItem : gameData.getHaveItems()) {
            if (haveItem.getId() > maxId) {
                maxId = haveItem.getId();
            }
        }
        EveFeastItem item = new EveFeastItem();
        item.setId(maxId + 1);
        item.setItemId(itemId);
        item.setExScore(itemConfig.getBaseScore());

        gameData.addHaveItem(item);

        //更新获得过的物品
//        gameData.getWasGetItems().addProperty(itemId, BigInteger.ONE);

        addItemIds.add(itemId);

        return item;
    }

    public EveFeastBlock randomPlaceItemOn(EveFeastGameData gameData, EveFeastItem item) {
        EveFeastBlock placeBlock = null;
        List<EveFeastBlock> emptyBlocks = new ArrayList<>();
        for (List<EveFeastBlock> blocks : gameData.getBlocks()) {
            for (EveFeastBlock block : blocks) {
                if (block.getObjectId() == 0) {
                    emptyBlocks.add(block);
                }
            }
        }
        int randomX = -1;
        int randomY = -1;
        EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.AddItem.getValue());
        showInfo.setItem(item.clone());
        if (!emptyBlocks.isEmpty()) {//随机一个空格摆放
            long idx = RandomHelper.nextLong(emptyBlocks.size());
            EveFeastBlock block = emptyBlocks.get((int) idx);
            block.setObjectId(item.getId());
            block.setItemId(item.getItemId());
            item.setBlock(block);

            placeBlock = block;
            showInfo.setBlock(block.cloneBlock());
            randomX = block.getX();
            randomY = block.getY();
        }
        addShow(showInfo);

        //日志用
        EveFeastLogItem logItem = new EveFeastLogItem();
        logItem.setItemId(item.getItemId());
        logItem.setId(item.getId());
        logItem.setExScore(item.getExScore());
        logItem.setMultiple(item.getMultiple());
        logItem.setX(randomX);
        logItem.setY(randomY);
        logItem.setEffectRound(item.getEffectRound());

        return placeBlock;
    }


    public EveFeastBlock addNewGameItem(EveFeastGameData gameData, int itemId) {
        EveFeastItem item = createNewGameItem(gameData, itemId);

        //获得道具要摆到盘面上
        return randomPlaceItemOn(gameData, item);
    }

    public void addChoseItem(EveFeastGameData gameData, int itemId) {
        EveFeastObjectConfig itemConfig = config.getItemConfig(itemId);
        if (itemConfig == null) {
            return;
        }

        gameData.getChoseItems().add(itemId);
    }

    /**
     * 选择祝酒词时,立即生效的处理
     *
     * @param gameData
     */
    public void handleChoseBuffEffect(EveFeastGameData gameData) {
        if (gameData.getHaveBuffs().isEmpty()) {
            return;
        }
        EveFeastBuffConfig buffConfig = config.getBuffConfig(gameData.getHaveBuffs().get(0));
        if (buffConfig == null) {
            return;
        }

        for (EveFeastBuffInfo feastBuffInfo : buffConfig.getBuffInfoList()) {
            if (feastBuffInfo.getBuffType() == eEveFeastBuffType.Type4.getValue()) {
                int itemId = feastBuffInfo.getBuffParam(0);
                int num = feastBuffInfo.getBuffParam(1);
                if (itemId == 0 || num == 0) {
                    continue;
                }
                for (int i = 0; i < num; i++) {
                    createNewGameItem(gameData, itemId);
                }

            } else if (feastBuffInfo.getBuffType() == eEveFeastBuffType.Type5.getValue()) {
                int quality = feastBuffInfo.getBuffParam(0);
                int num = feastBuffInfo.getBuffParam(1);
                if (num == 0) {
                    num = 1;
                }
                List<EveFeastObjectConfig> list = new ArrayList<>();
                for (EveFeastObjectConfig eveFeastObjectConfig : config.getObjectListByQuality(quality)) {
                    if (eveFeastObjectConfig.getLimitNum() > 0 && gameData.isItemHave(eveFeastObjectConfig.getObjectId())) {
                        continue;
                    }
                    list.add(eveFeastObjectConfig);
                }
                if (list == null || list.isEmpty()) {
                    continue;
                }
                Collections.shuffle(list);
                int itemId = list.get(0).getObjectId();
                for (int i = 0; i < num; i++) {
                    createNewGameItem(gameData, itemId);
                }
            } else if (feastBuffInfo.getBuffType() == eEveFeastBuffType.Type6.getValue()) {
                int refreshTimesAdd = feastBuffInfo.getBuffParam(0);
                int removeTimesAdd = feastBuffInfo.getBuffParam(1);

                gameData.setRefreshTimes(gameData.getRefreshTimes() + refreshTimesAdd);
                gameData.setRemoveTimes(gameData.getRemoveTimes() + removeTimesAdd);
            } else if (feastBuffInfo.getBuffType() == eEveFeastBuffType.Type7.getValue()) {
                int type = feastBuffInfo.getBuffParam(0);
                int num = feastBuffInfo.getBuffParam(1);
                EveFeastMissionConfig missionConfig = config.getMissionConfig(gameData.getTurnId());
                Map<Integer, Integer> weightMap = missionConfig.getObjectWeightByType(type);
                for (Integer itemId : weightMap.keySet()) {
                    EveFeastObjectConfig itemConfig = config.getItemConfig(itemId);
                    if (itemConfig == null) {
                        continue;
                    }
                    if (itemConfig.getLimitNum() > 0 && gameData.isItemHave(itemId)) {
                        weightMap.remove(itemId);
                    }
                }
                for (int i = 0; i < num; i++) {
                    int itemId = RandomHelper.getRandomKeyByWeight(weightMap);
                    createNewGameItem(gameData, itemId);
                }
            }
        }

    }

    /**
     * 开始从背包取道具随机放置,战令2效果,额外加分
     */
    public void startRandomPlaceItem(EveFeastGameData gameData, boolean isBuyToken1, boolean isBuyToken2, String testJson) {

        List<EveFeastBlock> allBlocks = new ArrayList<>();
        //先清空盘面
        for (List<EveFeastBlock> blocks : gameData.getBlocks()) {
            for (EveFeastBlock block : blocks) {
                block.clearItem();
                allBlocks.add(block);
            }
        }
        for (EveFeastItem haveItem : gameData.getHaveItems()) {
            haveItem.setBlock(null);
        }

        showGroupId = 1;

        if (!StringUtils.isNullOrEmpty(testJson)) {//测试用盘面
            JSONArray objects = JSON.parseArray(testJson);
            for (Object object : objects) {
                JSONObject jsonObject = (JSONObject) object;
                int x = jsonObject.getIntValue("x");
                int y = jsonObject.getIntValue("y");
                int id = jsonObject.getIntValue("id");
                EveFeastItem haveItem = gameData.getHaveItem(id);
                if (haveItem == null) {
                    continue;
                }

                haveItem.setEffectRound(haveItem.getEffectRound() + 1);//一开始放场上的物品回合+1

                EveFeastBlock block = gameData.getBlocks().get(y).get(x);
                firstPlaceOnBlock(block, haveItem);
            }
        } else {
            Collections.shuffle(allBlocks);

            List<EveFeastItem> haveItems = new ArrayList<>(gameData.getHaveItems());
            Collections.shuffle(haveItems);

            int itemTakeIndex = 0;
            //第一组表现,往空格上加物品
            for (EveFeastBlock block : allBlocks) {
                if (itemTakeIndex >= haveItems.size()) {
                    break;
                }
                EveFeastItem item = haveItems.get(itemTakeIndex++);
                firstPlaceOnBlock(block, item);
            }
        }


        //开始遍历道具效果
        for (int y = 0; y < gameData.getBlocks().size(); y++) {
            List<EveFeastBlock> blocks = gameData.getBlocks().get(y);
            for (int x = 0; x < blocks.size(); x++) {
                EveFeastBlock block = blocks.get(x);
                if (block.getObjectId() == 0) {
                    continue;
                }
                loopBlock = block;
                handleBlockTrigger(gameData, block);
            }
        }

        //遍历一次效果后,盘面稳定,处理稳定后的效果
        for (int y = 0; y < gameData.getBlocks().size(); y++) {
            List<EveFeastBlock> blocks = gameData.getBlocks().get(y);
            for (int x = 0; x < blocks.size(); x++) {
                EveFeastBlock block = blocks.get(x);
                if (block.getObjectId() == 0) {
                    continue;
                }

                handleLastBlockTrigger(gameData, block);
            }
        }
        showGroupId++;
        //处理祝酒词
        handlePreEndBuff(gameData);

        for (int y = 0; y < gameData.getBlocks().size(); y++) {
            List<EveFeastBlock> blocks = gameData.getBlocks().get(y);
            for (int x = 0; x < blocks.size(); x++) {
                EveFeastBlock block = blocks.get(x);
                if (block.getObjectId() == 0) {
                    continue;
                }

                handleMaxScoreCopyBlockTrigger(gameData, block);
            }
        }
        showGroupId++;

        //处理祝酒词
        handleEndBuff(gameData);
        //结算分数
        for (List<EveFeastBlock> blocks : gameData.getBlocks()) {
            for (EveFeastBlock block : blocks) {
                if (block.getObjectId() == 0) {
                    continue;
                }
                EveFeastItem haveItem = gameData.getHaveItem(block.getObjectId());
                if (haveItem == null) {
                    continue;
                }
                EveFeastObjectConfig itemConfig = config.getItemConfig(haveItem.getItemId());
                if (itemConfig == null) {
                    continue;
                }
                int addValue = haveItem.calcScore();
                addGameScore(gameData, addValue, block, false);
                //计算完重置临时分数
                haveItem.setTemporaryScore(0);
                haveItem.setTemporaryMultiple(0);
            }
        }
        //结算战令加的额外分
        int scoreMultiple = 0;
        if (isBuyToken1) {
            scoreMultiple += config.getToken1Params().get(2);
        }
        if (isBuyToken2) {
            scoreMultiple += config.getToken2Params().get(2);
        }
        if (scoreMultiple > 0) {
            showGroupId++;
            int tokenAddScore = BigDecimal.valueOf(scoreAmount).multiply(BigDecimal.valueOf(scoreMultiple).divide(BigDecimal.valueOf(1000))).setScale(0, BigDecimal.ROUND_UP).intValue();
            gameData.setScore(gameData.getScore() + tokenAddScore);
            gameData.setRemainScore(gameData.getRemainScore() + tokenAddScore);
            EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.TokenAddScore.getValue());
            showInfo.addParam(tokenAddScore);
            addShow(showInfo);
        }

        //回合结束没
        EveFeastMissionConfig missionConfig = config.getMissionConfig(gameData.getTurnId());
        if (gameData.getRound() >= missionConfig.getRound()) {//本轮最后一回合,判断分够不够扣
            if (gameData.getRemainScore() >= missionConfig.getCondition()) {//通关到下一轮
                //扣除雅趣值
                gameData.setRemainScore(gameData.getRemainScore() - missionConfig.getCondition());
                int nextTurnId = gameData.getTurnId() + 1;
                EveFeastMissionConfig nextMissionConfig = config.getMissionConfig(nextTurnId);
                if (nextMissionConfig == null) {
                    this.isEnd = true;
                    this.isPass = true;
                } else {
                    this.isNextTurn = true;
                    gameData.setTurnId(nextTurnId);
                    gameData.setRound(1);
                    //结算刷新次数
                    gameData.setRefreshTimes(gameData.getRefreshTimes() + nextMissionConfig.getRefreshTimes());
                    gameData.setRemoveTimes(gameData.getRemoveTimes() + nextMissionConfig.getRemoveTimes());
                    this.refreshAdd = nextMissionConfig.getRefreshTimes();
                    this.removeAdd = nextMissionConfig.getRemoveTimes();
                    //随机3个物品
                    List<Integer> itemIds = config.randomItemList(gameData, nextMissionConfig, 3);
                    for (Integer itemId : itemIds) {
                        addChoseItem(gameData, itemId);
                    }
                    //随机3个祝酒词
                    List<Integer> greetingIds = config.randomGreetingId(gameData, nextMissionConfig, 3);
                    gameData.getChoseBuffs().clear();
                    for (Integer greetingId : greetingIds) {
                        gameData.getChoseBuffs().add(greetingId);
                    }
                }
            } else {
                this.isEnd = true;
            }
        } else {//下一回合
            this.isNextRound = true;
            gameData.setRound(gameData.getRound() + 1);
            //随机3个物品
            List<Integer> itemIds = config.randomItemList(gameData, missionConfig, 3);
            for (Integer itemId : itemIds) {
                addChoseItem(gameData, itemId);
            }
        }

    }

    public void addShow(EveFeastShowInfo showInfo) {
        if (showInfo == null) {
            return;
        }
        while (showInfoListList.size() < showInfo.getGroupId()) {
            showInfoListList.add(new ArrayList<>());
        }
        showInfoListList.get(showInfo.getGroupId() - 1).add(showInfo);
    }

    public void firstPlaceOnBlock(EveFeastBlock block, EveFeastItem item) {
        item.setEffectRound(item.getEffectRound() + 1);//一开始放场上的物品回合+1

        block.setObjectId(item.getId());
        block.setItemId(item.getItemId());
        item.setBlock(block);

        EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.AddItem.getValue());
        showInfo.setBlock(block.cloneBlock());
        showInfo.setItem(item.clone());

        addShow(showInfo);

        //日志用
        EveFeastLogItem logItem = new EveFeastLogItem();
        logItem.setItemId(item.getItemId());
        logItem.setId(item.getId());
        logItem.setExScore(item.getExScore());
        logItem.setMultiple(item.getMultiple());
        logItem.setX(block.getX());
        logItem.setY(block.getY());
        logItem.setEffectRound(item.getEffectRound());
        initOnItemList.add(logItem);
    }

    /**
     * 处理非消除的触发
     *
     * @param gameData
     * @param block
     */
    public void handleBlockTrigger(EveFeastGameData gameData, EveFeastBlock block) {
        EveFeastItem item = gameData.getHaveItem(block.getObjectId());
        if (item == null) {
            return;
        }
        EveFeastObjectConfig itemConfig = config.getItemConfig(item.getItemId());
        if (itemConfig == null) {
            return;
        }

        for (EveFeastTriggerInfo triggerInfo : itemConfig.getTriggerInfoList()) {
            if (triggerInfo.getTriggerType() == eEveFeastTriggerType.Adjacent.getValue()) {//与指定物品相邻触发
                for (int y = block.getY() - 1; y <= block.getY() + 1; y++) {
                    for (int x = block.getX() - 1; x <= block.getX() + 1; x++) {
                        if (y == block.getY() && x == block.getX()) {
                            continue;
                        }
                        if (y < 0 || y >= gameData.getBlocks().size()) {
                            continue;
                        }
                        if (x < 0 || x >= gameData.getBlocks().get(y).size()) {
                            continue;
                        }
                        EveFeastBlock adjacentBlock = gameData.getBlocks().get(y).get(x);
                        if (adjacentBlock.getObjectId() == 0) {
                            continue;
                        }
                        if (!triggerInfo.getParams().contains(adjacentBlock.getItemId())) {
                            continue;
                        }

                        handleBlockEffect(gameData, block, item, triggerInfo, adjacentBlock);

                        if (block.getObjectId() == 0) {//消除了
                            break;
                        }
                    }
                    if (block.getObjectId() == 0) {//消除了
                        break;
                    }
                }
                continue;
            } else if (triggerInfo.getTriggerType() == eEveFeastTriggerType.Round.getValue()) {//每N回合放到盘面上触发
                if (item.getEffectRound() == 0) {
                    continue;
                }
                int checkRound = triggerInfo.getParams().get(0);
                if (!roundTriggerCheck(item.getEffectRound(), checkRound)) {
                    continue;
                }
            } else if (triggerInfo.getTriggerType() != eEveFeastTriggerType.Forever.getValue()) {
                continue;
            }

            handleBlockEffect(gameData, block, item, triggerInfo, null);
        }

        while (!waitTriggerBlockList.isEmpty()){
            EveFeastBlock waitTriggerBlock = waitTriggerBlockList.pop();
            handleBlockTrigger(gameData, waitTriggerBlock);
        }
    }

    private boolean roundTriggerCheck(int itemRound, int checkRound) {
        if (0 == checkRound) {
            return false;
        }
        if (itemRound % checkRound != 0) {
            return false;
        }
        return true;
    }

    /**
     * 是否与指定物品相邻
     */
    private boolean isAdjacent(List<EveFeastBlock> adjacentBlocks, EveFeastBlock block, List<Integer> checkItemIds) {
        boolean isAdjacent = false;
        for (EveFeastBlock adjacentBlock : adjacentBlocks) {
            if (adjacentBlock.getItemId() == 0) {
                continue;
            }
            if (checkItemIds.contains(adjacentBlock.getItemId())) {
                isAdjacent = true;
                break;
            }
        }
        return isAdjacent;
    }


    /**
     * 处理盘面稳定后的触发
     *
     * @param gameData
     * @param block
     */
    public void handleLastBlockTrigger(EveFeastGameData gameData, EveFeastBlock block) {
        EveFeastItem item = gameData.getHaveItem(block.getObjectId());
        if (item == null) {
            return;
        }
        EveFeastObjectConfig itemConfig = config.getItemConfig(item.getItemId());
        if (itemConfig == null) {
            return;
        }


        for (EveFeastTriggerInfo triggerInfo : itemConfig.getTriggerInfoList()) {
            if (triggerInfo.getTriggerType() == eEveFeastTriggerType.Round.getValue()) {//每N回合放到盘面上触发
                int checkRound = triggerInfo.getParams().get(0);
                if (!roundTriggerCheck(item.getEffectRound(), checkRound)) {
                    continue;
                }
            }

            handleLastBlockEffect(gameData, block, item, triggerInfo);
        }
    }

    /**
     * 最高分复制最后触发
     *
     * @param gameData
     * @param block
     */
    public void handleMaxScoreCopyBlockTrigger(EveFeastGameData gameData, EveFeastBlock block) {
        EveFeastItem item = gameData.getHaveItem(block.getObjectId());
        if (item == null) {
            return;
        }
        EveFeastObjectConfig itemConfig = config.getItemConfig(item.getItemId());
        if (itemConfig == null) {
            return;
        }

        for (EveFeastTriggerInfo triggerInfo : itemConfig.getTriggerInfoList()) {
            if (triggerInfo.getTriggerType() == eEveFeastTriggerType.Round.getValue()) {//每N回合放到盘面上触发
                int checkRound = triggerInfo.getParams().get(0);
                if (!roundTriggerCheck(item.getEffectRound(), checkRound)) {
                    continue;
                }
            }

            handleMaxScoreCopy(gameData, block, item, triggerInfo);
        }
    }

    /**
     * 处理消除触发
     *
     * @param triggerBlock 触发消除的格子
     */
    public void handleBlockEliminateTrigger(EveFeastGameData gameData, EveFeastBlock block, EveFeastBlock triggerBlock) {
        if (block.getObjectId() == 0) {
            return;
        }

        EveFeastItem item = gameData.getHaveItem(block.getObjectId());
        if (item == null) {
            return;
        }
        EveFeastObjectConfig itemConfig = config.getItemConfig(item.getItemId());
        if (itemConfig == null) {
            return;
        }

        for (EveFeastTriggerInfo triggerInfo : itemConfig.getTriggerInfoList()) {
            if (triggerInfo.getTriggerType() != eEveFeastTriggerType.EliminateSelf.getValue()) {
                continue;
            }

            handleBlockEffect(gameData, block, item, triggerInfo, triggerBlock);
        }

        //消除相关的BUFF
        handleBuffType1(gameData, block);

        EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.Eliminate.getValue());
        showInfo.setBlock(block.cloneBlock());
        showInfo.setItem(item.clone());
        addShow(showInfo);

        //处理效果后,再消除掉
        //日志用
        EveFeastLogItem logItem = new EveFeastLogItem();
        logItem.setItemId(item.getItemId());
        logItem.setId(item.getId());
        logItem.setExScore(item.getExScore());
        logItem.setMultiple(item.getMultiple());
        logItem.setX(block.getX());
        logItem.setY(block.getY());
        logItem.setEffectRound(item.getEffectRound());
        eliminateItemList.add(logItem);

        block.clearItem();
        gameData.removeItem(item);
    }


    /**
     * 处理触发效果
     */
    public void handleBlockEffect(EveFeastGameData gameData, EveFeastBlock block, EveFeastItem blockItem, EveFeastTriggerInfo triggerInfo, EveFeastBlock triggerBlock) {
        if (triggerInfo.getEffectInfoList().isEmpty()) {
            return;
        }

        for (EveFeastEffectInfo effectInfo : triggerInfo.getEffectInfoList()) {
            if (effectInfo.getEffectType() == eEveFeastEffectType.Eliminate.getValue()) {//概率消除
                //概率千分比
                long rate = effectInfo.getParams().get(0);
                if (!checkRate(rate)) {
                    continue;
                }

                //消除类型 0自己 1是触发的检测id列表
                int eliminateType = effectInfo.getParams().get(1);
                List<EveFeastBlock> checkBlocks = getAddTypeBlocks(eliminateType, gameData, block, triggerInfo.getParams(), triggerBlock);
                if (!checkBlocks.isEmpty()) {
                    addLightUpShow(block, triggerBlock, effectInfo.getEffectType());
                    for (EveFeastBlock checkBlock : checkBlocks) {
                        handleBlockEliminateTrigger(gameData, checkBlock, block);
                    }
                }
            } else if (effectInfo.getEffectType() == eEveFeastEffectType.AddItem.getValue()) {
                //概率千分比
                long rate = effectInfo.getParams().get(0);
                if (!checkRate(rate)) {
                    continue;
                }

                //过滤有数量限制的物品
                List<PropertyWeightItem> propertyWeightItems = new ArrayList<>();
                int listSize = (effectInfo.getParams().size() - 1) / 3;
                for (int i = 0; i < listSize; i++) {
                    int itemId = effectInfo.getParams().get(i * 3 + 1);
                    EveFeastObjectConfig itemConfig = config.getItemConfig(itemId);
                    if (itemConfig == null) {
                        continue;
                    }
                    if (itemConfig.getLimitNum() > 0 && gameData.isItemHave(itemId)) {
                        //有数量限制的物品,已经有了就不再添加
                        continue;
                    }

                    int num = effectInfo.getParams().get(i * 3 + 2);
                    int weight = effectInfo.getParams().get(i * 3 + 3);
                    propertyWeightItems.add(new PropertyWeightItem(new Property(itemId, num), weight));
                }

                if (!propertyWeightItems.isEmpty()) {
                    addLightUpShow(block, triggerBlock, effectInfo.getEffectType());
                    //添加物品
                    Property result = RandomWeightConfigHelper.getPropertyWeightItem(propertyWeightItems);
                    for (Map.Entry<Integer, BigInteger> entry : result.getGoods().entrySet()) {
                        int addNum = entry.getValue().intValue();
                        int itemId = entry.getKey();
                        for (int i = 0; i < addNum; i++) {
                            EveFeastBlock placeBlock = addNewGameItem(gameData, itemId);
                            //放置物品后的位置在当前格子前的要先处理触发效果
                            if (placeBlock != null) {
                                if (placeBlock.getY() < loopBlock.getY() || (placeBlock.getY() == loopBlock.getY() && placeBlock.getX() < loopBlock.getX())) {
                                    waitTriggerBlockList.addLast(placeBlock);
                                }
                            }
                        }
                    }
                }
            } else if (effectInfo.getEffectType() == eEveFeastEffectType.AddItemValue.getValue()) {
                //概率千分比
                long rate = effectInfo.getParams().get(0);
                if (!checkRate(rate)) {
                    continue;
                }

                EveFeastItem item = gameData.getHaveItem(block.getObjectId());
                if (item == null) {
                    continue;
                }

                int addValue = randomHelper.next(effectInfo.getParams().get(1), effectInfo.getParams().get(2));
                int addType = effectInfo.getParams().get(3);//0 加自己 1 加触发的检测id列表
                int multiple = effectInfo.getParams().get(4);//倍数
                List<EveFeastBlock> addTypeBlocks = getAddTypeBlocks(addType, gameData, block, triggerInfo.getParams(), triggerBlock);
                if (!addTypeBlocks.isEmpty()) {
                    addLightUpShow(block, triggerBlock, effectInfo.getEffectType());

                    for (EveFeastBlock addTypeBlock : addTypeBlocks) {
                        addBlockItemValue(addTypeBlock, gameData.getHaveItem(addTypeBlock.getObjectId()), addValue, multiple, false);
                    }
                }
            } else if (effectInfo.getEffectType() == eEveFeastEffectType.AddScore.getValue()) {
                //概率千分比
                long rate = effectInfo.getParams().get(0);
                if (!checkRate(rate)) {
                    continue;
                }
                int addValue = randomHelper.next(effectInfo.getParams().get(1), effectInfo.getParams().get(2));
                int addType = effectInfo.getParams().get(3);//0 加自己 1 加触发的检测id列表
                int multiple = effectInfo.getParams().get(4);//倍数

                List<EveFeastBlock> addTypeBlocks = getAddTypeBlocks(addType, gameData, block, triggerInfo.getParams(), triggerBlock);
                if (!addTypeBlocks.isEmpty()) {
                    addLightUpShow(block, triggerBlock, effectInfo.getEffectType());

                    for (EveFeastBlock addTypeBlock : addTypeBlocks) {
                        addBlockTemporaryScore(gameData, addTypeBlock, addValue, multiple);
                    }
                }
            } else if (effectInfo.getEffectType() == eEveFeastEffectType.Transform.getValue()) {
                //概率千分比
                long rate = effectInfo.getParams().get(0);
                if (!checkRate(rate)) {
                    continue;
                }

                Map<Integer, Integer> weightKeyMap = new HashMap<>();
                int listSize = (effectInfo.getParams().size() - 1) / 2;
                for (int i = 0; i < listSize; i++) {
                    int itemId = effectInfo.getParams().get(i * 2 + 1);
                    int weight = effectInfo.getParams().get(i * 2 + 2);

                    EveFeastObjectConfig itemConfig = config.getItemConfig(itemId);
                    if (itemConfig == null) {
                        continue;
                    }
                    if (itemConfig.getLimitNum() > 0 && gameData.isItemHave(itemId)) {
                        //有数量限制的物品,已经有了就不再添加
                        continue;
                    }

                    weightKeyMap.put(itemId, weight);
                }
                int itemId = RandomHelper.getRandomKeyByWeight(weightKeyMap);
                EveFeastObjectConfig itemConfig = config.getItemConfig(itemId);
                if (itemConfig == null) {
                    continue;
                }

                EveFeastItem haveItem = gameData.getHaveItem(block.getObjectId());
                if (haveItem == null) {
                    continue;
                }
                addLightUpShow(block, triggerBlock, effectInfo.getEffectType());
                haveItem.setItemId(itemId);
                haveItem.setEffectRound(0);
                haveItem.setExScore(itemConfig.getBaseScore());
                block.setItemId(itemId);
                EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.ChangeItem.getValue());
                showInfo.setBlock(block.cloneBlock());
                showInfo.setItem(haveItem.clone());
                addShow(showInfo);

                //变化后再触发下效果
                handleBlockTrigger(gameData, block);
            } else if (effectInfo.getEffectType() == eEveFeastEffectType.Type9.getValue()) {
                //给物品加自身雅趣值"),//概率千分比|对象对象：1 相邻检测列表，通用：物品ID
                //概率千分比
                long rate = effectInfo.getParams().get(0);
                if (!checkRate(rate)) {
                    continue;
                }
                int blockScore = blockItem.calcScore();
                int addType = effectInfo.getParams().get(1);
                List<EveFeastBlock> addTypeBlocks = getAddTypeBlocks(addType, gameData, block, triggerInfo.getParams(), triggerBlock);
                if (!addTypeBlocks.isEmpty()) {
                    addLightUpShow(block, triggerBlock, effectInfo.getEffectType());

                    for (EveFeastBlock addTypeBlock : addTypeBlocks) {
                        addBlockItemValue(addTypeBlock, gameData.getHaveItem(addTypeBlock.getObjectId()), blockScore, 0, false);
                    }
                }
            } else if (effectInfo.getEffectType() == eEveFeastEffectType.Type10.getValue()) {
                long rate = effectInfo.getParams().get(0);
                if (!checkRate(rate)) {
                    continue;
                }
                int addValue = randomHelper.next(effectInfo.getParams().get(1), effectInfo.getParams().get(2));
                int addMultiple = effectInfo.getParams().get(3);

                int addScore = BigDecimal.valueOf(blockItem.calcScore()).multiply(BigDecimal.valueOf(addMultiple).divide(BigDecimal.valueOf(1000))).add(BigDecimal.valueOf(addValue)).setScale(0, BigDecimal.ROUND_UP).intValue();
                addLightUpShow(block, triggerBlock, effectInfo.getEffectType());
                addGameScore(gameData, addScore, block, false);
            }
        }
    }

    /**
     * 处理盘面稳定后的触发效果
     */
    public void handleLastBlockEffect(EveFeastGameData gameData, EveFeastBlock block, EveFeastItem item, EveFeastTriggerInfo triggerInfo) {
        if (triggerInfo.getEffectInfoList().isEmpty()) {
            return;
        }

        for (EveFeastEffectInfo effectInfo : triggerInfo.getEffectInfoList()) {
            if (effectInfo.getEffectType() == eEveFeastEffectType.SelfScoreSum.getValue()) {
                int checkType = effectInfo.getParams().get(0);
                for (EveFeastItem haveItem : gameData.getHaveItems()) {
                    if (haveItem.getBlock() == null){
                        continue;
                    }

                    EveFeastObjectConfig itemConfig = config.getItemConfig(haveItem.getItemId());
                    if (itemConfig == null) {
                        continue;
                    }

                    if (itemConfig.getType() == checkType) {
                        int itemScore = haveItem.calcScore();
                        addLightUpShow(block, haveItem.getBlock(), effectInfo.getEffectType());
                        addBlockTemporaryScore(gameData, block, itemScore, 0);
                    }
                }
            } else if (effectInfo.getEffectType() == eEveFeastEffectType.Type8.getValue()) {
                //场上每有一个某物品自身价值加n"//物品ID|增加固定值
                int checkItemId = effectInfo.getParams().get(0);
                int addValue = effectInfo.getParams().get(1);
                for (List<EveFeastBlock> blocks : gameData.getBlocks()) {
                    for (EveFeastBlock checkBlock : blocks) {
                        if (checkBlock.getItemId() == 0) {
                            continue;
                        }
                        if (checkBlock.getItemId() == checkItemId) {
                            addLightUpShow(block, checkBlock, effectInfo.getEffectType());
                            addBlockItemValue(block, item, addValue, 0, false);
                        }
                    }
                }
            }
        }
    }

    public void handleMaxScoreCopy(EveFeastGameData gameData, EveFeastBlock block, EveFeastItem item, EveFeastTriggerInfo triggerInfo) {
        if (triggerInfo.getEffectInfoList().isEmpty()) {
            return;
        }

        for (EveFeastEffectInfo effectInfo : triggerInfo.getEffectInfoList()) {
            if (effectInfo.getEffectType() == eEveFeastEffectType.MaxScoreCopy.getValue()) {
                int maxScore = 0;
                EveFeastBlock maxBlock = null;
                for (List<EveFeastBlock> blocks : gameData.getBlocks()) {
                    for (EveFeastBlock checkBlock : blocks) {
                        if (checkBlock.getItemId() == 0) {
                            continue;
                        }
                        EveFeastObjectConfig itemConfig = config.getItemConfig(checkBlock.getItemId());
                        if (itemConfig == null) {
                            continue;
                        }
                        EveFeastItem haveItem = gameData.getHaveItem(checkBlock.getObjectId());
                        if (haveItem == null) {
                            continue;
                        }
                        int itemScore = haveItem.calcScore();
                        if (itemScore > maxScore) {
                            maxScore = itemScore;
                            maxBlock = checkBlock;
                        }
                    }
                }
                if (maxScore > 0) {
                    addLightUpShow(block, maxBlock, effectInfo.getEffectType());
                    addBlockTemporaryScore(gameData, block, maxScore, 0);
                }
            }
        }
    }

    //千分比概率判断是否通过
    private boolean checkRate(long rate) {
        long compareValue = randomHelper.nextLong(1000l);
        return compareValue <= rate;
    }

    /**
     * 加格子上的物品价值和倍率
     *
     * @param block
     */
    private void addBlockItemValue(EveFeastBlock block, EveFeastItem item, int addValue, int addMultiple, boolean isBuffEffect) {
        if (item == null) {
            return;
        }

        int oldScore = item.calcScore();
        item.setExScore(item.getExScore() + addValue);
        item.setMultiple(item.getMultiple() + addMultiple);
        int newScore = item.calcScore();

        EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.AddScore.getValue());
        if (block != null) {
            showInfo.setBlock(block.cloneBlock());
        }

        showInfo.setItem(item.clone());
        showInfo.addParam(newScore - oldScore);
        showInfo.setBuffEffect(isBuffEffect);

        addShow(showInfo);
    }

    private void addBlockTemporaryScore(EveFeastGameData gameData, EveFeastBlock block, int addValue, int addMultiple) {
        EveFeastItem item = gameData.getHaveItem(block.getObjectId());
        if (item == null) {
            return;
        }
        int oldScore = item.calcScore();
        item.setTemporaryScore(item.getTemporaryScore() + addValue);
        item.setTemporaryMultiple(item.getTemporaryMultiple() + addMultiple);
        int newScore = item.calcScore();

        EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.AddScore.getValue());
        showInfo.setBlock(block.cloneBlock());
        showInfo.setItem(item.clone());
        showInfo.addParam(newScore - oldScore);

        addShow(showInfo);
    }

    /**
     * 处理祝酒词效果1 消除物品，获得其雅趣值n1倍
     *
     * @param gameData
     * @param block
     */
    public void handleBuffType1(EveFeastGameData gameData, EveFeastBlock block) {
        if (block.getItemId() == 0) {
            return;
        }
        for (Integer buffId : gameData.getHaveBuffs()) {
            EveFeastBuffConfig buffConfig = config.getBuffConfig(buffId);
            if (buffConfig == null) {
                continue;
            }
            for (EveFeastBuffInfo buffInfo : buffConfig.getBuffInfoList()) {
                if (buffInfo.getBuffType() != eEveFeastBuffType.Type1.getValue()) {
                    continue;
                }
                int multiple = buffInfo.getBuffParam(0);

                EveFeastItem haveItem = gameData.getHaveItem(block.getObjectId());
                if (haveItem == null) {
                    continue;
                }
                EveFeastObjectConfig itemConfig = config.getItemConfig(haveItem.getItemId());
                if (itemConfig == null) {
                    continue;
                }
                int score = haveItem.calcScore();
                int scoreAdd = BigDecimal.valueOf(score).multiply(BigDecimal.valueOf(multiple).divide(BigDecimal.valueOf(1000), 2, BigDecimal.ROUND_UP)).setScale(0, BigDecimal.ROUND_UP).intValue();
                addGameScore(gameData, scoreAdd, block, true);
            }
        }
    }

    public void addGameScore(EveFeastGameData gameData, int addValue, EveFeastBlock block, boolean isBuffEffect) {
        gameData.setScore(gameData.getScore() + addValue);
        gameData.setRemainScore(gameData.getRemainScore() + addValue);

        EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.GetTotalScore.getValue());
        if (block != null) {
            showInfo.setBlock(block.cloneBlock());
        }
        showInfo.addParam(addValue);
        showInfo.setBuffEffect(isBuffEffect);

        addShow(showInfo);

        this.scoreAmount += addValue;
    }

    /**
     * 盘面稳定后,需要处理的buff
     *
     * @param gameData
     */
    public void handleEndBuff(EveFeastGameData gameData) {
        for (Integer buffId : gameData.getHaveBuffs()) {
            EveFeastBuffConfig buffConfig = config.getBuffConfig(buffId);
            if (buffConfig == null) {
                continue;
            }
            for (EveFeastBuffInfo buffInfo : buffConfig.getBuffInfoList()) {
                if (buffInfo.getBuffType() == eEveFeastBuffType.Type3.getValue()) {
                    int numNeed = buffInfo.getBuffParam(0);
                    int checkQuality = buffInfo.getBuffParam(1);
                    for (List<EveFeastBlock> blocks : gameData.getBlocks()) {
                        for (EveFeastBlock checkBlock : blocks) {
                            if (checkBlock.getItemId() == 0) {
                                continue;
                            }
                            EveFeastObjectConfig itemConfig = config.getItemConfig(checkBlock.getItemId());
                            if (itemConfig == null) {
                                continue;
                            }
                            if (itemConfig.getQuality() == checkQuality) {
                                numNeed--;
                                if (numNeed <= 0) {
                                    int scoreAdd = buffInfo.getBuffParam(2);
                                    addGameScore(gameData, scoreAdd, checkBlock, true);
                                    numNeed = buffInfo.getBuffParam(0);
                                }
                            }
                        }
                    }

                }
            }
        }
    }

    /**
     * 盘面稳定后,需要处理的buff
     *
     * @param gameData
     */
    public void handlePreEndBuff(EveFeastGameData gameData) {
        for (Integer buffId : gameData.getHaveBuffs()) {
            EveFeastBuffConfig buffConfig = config.getBuffConfig(buffId);
            if (buffConfig == null) {
                continue;
            }
            for (EveFeastBuffInfo buffInfo : buffConfig.getBuffInfoList()) {
                if (buffInfo.getBuffType() == eEveFeastBuffType.Type2.getValue()) {
                    int checkQuality = buffInfo.getBuffParam(0);
                    int addValue = buffInfo.getBuffParam(1);
                    for (EveFeastItem item : gameData.getHaveItems()) {
                        EveFeastObjectConfig itemConfig = config.getItemConfig(item.getItemId());
                        if (itemConfig == null) {
                            continue;
                        }
                        if (itemConfig.getQuality() == checkQuality) {
                            addBlockItemValue(item.getBlock(), item, addValue, 0, true);
                        }
                    }
                } else if (buffInfo.getBuffType() == eEveFeastBuffType.Type8.getValue()) {
                    int checkType = buffInfo.getBuffParam(0);
                    int addValue = buffInfo.getBuffParam(1);
                    for (EveFeastItem haveItem : gameData.getHaveItems()) {
                        if (haveItem.getBlock() == null){
                            continue;
                        }
                        EveFeastObjectConfig itemConfig = config.getItemConfig(haveItem.getItemId());
                        if (itemConfig == null) {
                            continue;
                        }
                        if (itemConfig.getType() == checkType) {
                            addBlockItemValue(haveItem.getBlock(), haveItem, addValue, 0, true);
                        }
                    }
                } else if (buffInfo.getBuffType() == eEveFeastBuffType.Type9.getValue()) {
                    int checkItemId = buffInfo.getBuffParam(0);
                    int addValue = buffInfo.getBuffParam(1);
                    for (EveFeastItem haveItem : gameData.getHaveItems()) {
                        if (haveItem.getBlock() == null){
                            continue;
                        }
                        if (haveItem.getItemId() == checkItemId) {
                            addBlockItemValue(null, haveItem, addValue, 0, true);
                        }
                    }
                } else if (buffInfo.getBuffType() == eEveFeastBuffType.Type10.getValue()) {
                    int checkItemId = buffInfo.getBuffParam(0);
                    int addMultiple = buffInfo.getBuffParam(1);
                    for (EveFeastItem haveItem : gameData.getHaveItems()) {
                        if (haveItem.getBlock() == null){
                            continue;
                        }
                        if (haveItem.getItemId() == checkItemId) {
                            addBlockItemValue(haveItem.getBlock(), haveItem, 0, addMultiple, true);
                        }
                    }
                }
            }
        }
    }

    public List<List<EveFeastShowInfo>> getShowInfoListList() {
        return showInfoListList;
    }

    public boolean isNextRound() {
        return isNextRound;
    }

    public boolean isNextTurn() {
        return isNextTurn;
    }

    public boolean isEnd() {
        return isEnd;
    }

    public boolean isPass() {
        return isPass;
    }

    public int getRefreshAdd() {
        return refreshAdd;
    }

    public int getRemoveAdd() {
        return removeAdd;
    }

    /**
     * 有触发效果的格子都要添加一下
     *
     * @param block
     */
    public void addLightUpShow(EveFeastBlock block, EveFeastBlock triggerBlock, int effectType) {
        if (block == null) {
            return;
        }
        if (block.getObjectId() == 0) {
            return;
        }
//        if (lastShowBlock == null || block.getX() != lastShowBlock.getX() || block.getY() != lastShowBlock.getY()) {
//            showGroupId++;
//            lastShowBlock = block;
//        }
        showGroupId++;
        EveFeastShowInfo showInfo = new EveFeastShowInfo(showGroupId, eEveFeastShowType.LightUp.getValue());
        showInfo.setBlock(block.cloneBlock());
        if (triggerBlock != null){
            showInfo.setTriggerBlock(triggerBlock.cloneBlock());
        }
        showInfo.addParam(effectType);
        addShow(showInfo);
    }

    /**
     * 根据对象类型取格子
     * addType=0 自己
     * addType=1 取相邻指定对象
     * addType>1 取场上指定对象
     */
    public List<EveFeastBlock> getAddTypeBlocks(int addType, EveFeastGameData gameData, EveFeastBlock checkBlock, List<Integer> triggerItemIds, EveFeastBlock triggerBlock) {
        List<EveFeastBlock> resultBlocks = new ArrayList<>();
        if (addType == 0) {
            resultBlocks.add(checkBlock);
        } else if (addType == 1) {
            if (triggerBlock != null) {
                if (triggerItemIds.contains(triggerBlock.getItemId())) {
                    resultBlocks.add(triggerBlock);
                }
            }
        }else {
            for (List<EveFeastBlock> blocks : gameData.getBlocks()) {
                for (EveFeastBlock block : blocks) {
                    if (block.getItemId() == 0) {
                        continue;
                    }
                    if (block.getItemId() == addType) {
                        resultBlocks.add(block);
                    }
                }
            }
        }

        return resultBlocks;
    }

    public List<Integer> getAddItemIds() {
        return addItemIds;
    }

    public List<EveFeastLogItem> getInitOnItemList() {
        return initOnItemList;
    }

    public List<EveFeastLogItem> getEliminateItemList() {
        return eliminateItemList;
    }

    public List<EveFeastLogItem> getAddPlaceOnItemList() {
        return addPlaceOnItemList;
    }
}
